#pragma once

#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<boost/algorithm/string.hpp>
#include"cppjieba/Jieba.hpp"
#include"log.hpp"
#include<mutex>

//设置字体颜色
#ifndef COLOR
#define COLOR
#define RESET "\033[0m"
#define RED "\033[31m"    /* Red */
#define GREEN "\033[32m"   /* Green */
#endif

namespace ns_util {
    //读文件的工具类
    class FileUtil {
    public:
        static bool ReadFile(const std::string& file_path, std::string* out) {
            std::ifstream in(file_path, std::ios::in);
            //用文件流的方式打开文件
            if (!in.is_open()) {
                std::cerr << RED << "open file:" << file_path << " error!" << RESET << std::endl;
                return false;
            }
            //读文件
            std::string line;
            while (getline(in, line)) {
                *out += line;
            }
            //关闭文件
            in.close();
            return true;
        }
    };

    //实现字符串分割的工具类
    class StringUtil {
    public:
        static bool Split(const std::string& target, std::vector<std::string>* out, const std::string& sep) {
            //利用boost库中的字符串分割函数，实现字符串分割
            //最后一个参数表示是否实现压缩，例如："\3abc\3\3\3ggggc"，中间的一连串的\3会被当成一个\3
            boost::split(*out, target, boost::is_any_of(sep), boost::token_compress_on);
            if ((*out).size() != 3) {
                std::cout << (*out).size() << std::endl;
                return false;
            }
            return true;
        }
    };

    //jieba分词需要的路径
    const char* const DICT_PATH = "./dict/jieba.dict.utf8";
    const char* const HMM_PATH = "./dict/hmm_model.utf8";
    const char* const USER_DICT_PATH = "./dict/user.dict.utf8";
    const char* const IDF_PATH = "./dict/idf.utf8";
    const char* const STOP_WORD_PATH = "./dict/stop_words.utf8";
    
    class JiebaUtil {
    public:
        void InitJiebaUtil() {
            //打开暂停词相关文件
            std::ifstream in(STOP_WORD_PATH);
            if (!in.is_open()) {
                LOG(FATAL, "Loads stop words file failed!");
                return;
            }
            
            std::string line;
            while (getline(in, line)) {
                stop_words_.insert({line, true});
            }

            in.close();
        }

        void CurStringHelper(const std::string& src, std::vector<std::string>* out) {

            jieba_.CutForSearch(src, *out);
            for (auto iter = out->begin(); iter != out->end(); ) {
                if (stop_words_.find(*iter) != stop_words_.end()) {
                    //当前词是暂停词，需要去掉
                    iter = out->erase(iter);
                }
                else {
                    ++iter;
                }
            }
        }

        static JiebaUtil* get_instance() {
            static std::mutex mtx;
            if (nullptr == instance_) {
                mtx.lock();
                if (nullptr == instance_) {
                    instance_ = new JiebaUtil();
                    instance_->InitJiebaUtil();
                }
                mtx.unlock();
            }
            return instance_;
        }

        //src表示我们要切分的数据，out表示切分后的存储
        static void CurStr(const std::string& src, std::vector<std::string>* out) {

            //jieba_.CutForSearch(src, *out);
            ns_util::JiebaUtil::get_instance()->CurStringHelper(src, out);
        }

    private:

        JiebaUtil() :jieba_(DICT_PATH, HMM_PATH, USER_DICT_PATH, IDF_PATH, STOP_WORD_PATH) {}
        JiebaUtil(const JiebaUtil&) = delete;
        JiebaUtil& operator=(const JiebaUtil&) = delete;

        static JiebaUtil* instance_;

        cppjieba::Jieba jieba_;
        std::unordered_map<std::string, bool> stop_words_;
    };

    JiebaUtil* JiebaUtil::instance_ = nullptr;

    // cppjieba::Jieba JiebaUtil::jieba (
        // DICT_PATH,
        // HMM_PATH,
        // USER_DICT_PATH,
        // IDF_PATH,
        // STOP_WORD_PATH
    // );
}